﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace AudioTest
{
    public partial class AudioTestDialog : Form
    {

        public AudioTestDialog()
        {
            InitializeComponent();

        }

        void ac_OnAudiosamplesAvailable(float[] data, int SamplesPerSecond)
        {
            foreach (float f in data)
            {
                System.Diagnostics.Debug.WriteLine(f.ToString());
            }
        }


        PayloadTracker.APRS.SoundModem.FSK fsk;
        PayloadTracker.APRS.SoundModem.AX25Deserializer ax25;
        private void Form1_Load(object sender, EventArgs e)
        {

            foreach (var d in PayloadTracker.APRS.SoundModem.FSK.GetAvailableDevices())
                System.Diagnostics.Debug.WriteLine(d.ID + ": " + d.Name);

            tr = new System.IO.StreamWriter(System.IO.File.Open("dump.txt", System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.Read));

            this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);
        }

        void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {

            tr.Flush();
            ((System.IO.StreamWriter)tr).BaseStream.Flush();
            ((System.IO.StreamWriter)tr).BaseStream.Close();


            if(fsk != null)
                fsk.Stop();
            
        }



        private void button1_Click(object sender, EventArgs e)
        {

            fsk = new PayloadTracker.APRS.SoundModem.FSK(new PayloadTracker.APRS.SoundModem.FSK.ModemDeffinition(2200, 1200, 1200, 44100), 0);
            ax25 = new PayloadTracker.APRS.SoundModem.AX25Deserializer();
            ax25.AX25PacketReady += new PayloadTracker.APRS.SoundModem.AX25PacketReadyDelegate(ax25_AX25PacketReady);
            fsk.FSKBitReady += new PayloadTracker.APRS.SoundModem.FSKBitReadyDelegate(ax25.ProcessBit);

            
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == DialogResult.OK)
            {

                using (var ws = new WaveLib.WaveStream(ofd.FileName))
                {

                    ws.Seek(0, System.IO.SeekOrigin.Begin);
                    var bs = new System.IO.BinaryReader(ws);

                    while (bs.BaseStream.Position != bs.BaseStream.Length)
                    {
                        fsk.ProcessSample((bs.ReadInt16() / 32768.0f) * 0.5);
                    }

                }

            }


            //fsk.Start();
        }

        System.IO.TextWriter tr;
        void fsk_FSKBitReady(bool bit)
        {
            tr.Write(bit?"1":"0");
            tr.Flush();
        }

        void ax25_AX25PacketReady(PayloadTracker.APRS.SoundModem.AX25Packet packet)
        {
            textBox1.BeginInvoke((MethodInvoker)delegate()
            {
                textBox1.Text += "\r\nFrom: " + packet.CallsignFrom;
                textBox1.Text += "\r\nFromSSID: " + packet.SSIDFrom;
                textBox1.Text += "\r\nTo: " + packet.CallsignTo;
                textBox1.Text += "\r\nToSSID: " + packet.SSIDTo;
                textBox1.Text += "\r\nData: " + System.Text.ASCIIEncoding.ASCII.GetString(packet.Data) + "\r\n";
                textBox1.SelectionStart = textBox1.Text.Length;
                textBox1.ScrollToCaret();
            });
        }
        void ax25_AX25PacketReadyEncode(PayloadTracker.APRS.SoundModem.AX25Packet packet)
        {
            PayloadTracker.APRS.SoundModem.AX25Serializer axs = new PayloadTracker.APRS.SoundModem.AX25Serializer();
            var bin = axs.Serialize(packet);
            var modem = new PayloadTracker.APRS.SoundModem.FSK.ModemDeffinition(2200, 1200, 1200, 44100);
            var mod = new PayloadTracker.APRS.SoundModem.Modulator(modem);
            var modulated = mod.Modulate(bin);

            
            var demod = new PayloadTracker.APRS.SoundModem.AX25Deserializer();
            demod.AX25PacketReady += new PayloadTracker.APRS.SoundModem.AX25PacketReadyDelegate(ax25_AX25PacketReady);
            var refsk = new PayloadTracker.APRS.SoundModem.FSK(modem, 0);
            refsk.FSKBitReady +=new PayloadTracker.APRS.SoundModem.FSKBitReadyDelegate(demod.ProcessBit);


            foreach (byte b in bin)
            {
                string bitstring = Convert.ToString(b, 2);
                while (bitstring.Length < 8)
                    bitstring = "0" + bitstring;

                System.Diagnostics.Debug.WriteLine("Byte: " + bitstring + " H: 0x" + Convert.ToString(b, 16) + " D: " + b.ToString() + " A: " + System.Text.ASCIIEncoding.ASCII.GetString(new byte[] { b }));

            }

            System.Diagnostics.Debug.WriteLine("Trying to deemodulate again..");


            foreach (var s in modulated)
            {
                refsk.ProcessSample(s);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            fsk = new PayloadTracker.APRS.SoundModem.FSK(new PayloadTracker.APRS.SoundModem.FSK.ModemDeffinition(2200, 1200, 1200, 44100), 0);
            ax25 = new PayloadTracker.APRS.SoundModem.AX25Deserializer();
            ax25.AX25PacketReady += new PayloadTracker.APRS.SoundModem.AX25PacketReadyDelegate(ax25_AX25PacketReady);
            fsk.FSKBitReady += new PayloadTracker.APRS.SoundModem.FSKBitReadyDelegate(fsk_FSKBitReady);
            fsk.FSKBitReady += new PayloadTracker.APRS.SoundModem.FSKBitReadyDelegate(ax25.ProcessBit);
            fsk.Start();

        }

        private void button3_Click(object sender, EventArgs e)
        {
            ax25 = new PayloadTracker.APRS.SoundModem.AX25Deserializer();
            ax25.AX25PacketReady += new PayloadTracker.APRS.SoundModem.AX25PacketReadyDelegate(ax25_AX25PacketReady);

            System.IO.TextReader tr = new System.IO.StreamReader(System.IO.File.OpenRead("error.txt"));
            var str = tr.ReadToEnd();

            foreach(char c in str)
            {
                System.Diagnostics.Debug.Write(c);
                if (c == '1')
                    ax25.ProcessBit(true);
                else if (c == '0')
                    ax25.ProcessBit(false);
            }

            tr.Close();
        }

        private void button4_Click(object sender, EventArgs e)
        {

            fsk = new PayloadTracker.APRS.SoundModem.FSK(new PayloadTracker.APRS.SoundModem.FSK.ModemDeffinition(2200, 1200, 1200, 44100), 0);
            ax25 = new PayloadTracker.APRS.SoundModem.AX25Deserializer();
            ax25.AX25PacketReady += new PayloadTracker.APRS.SoundModem.AX25PacketReadyDelegate(ax25_AX25PacketReady);
            ax25.AX25PacketReady +=new PayloadTracker.APRS.SoundModem.AX25PacketReadyDelegate(ax25_AX25PacketReadyEncode);
            fsk.FSKBitReady += new PayloadTracker.APRS.SoundModem.FSKBitReadyDelegate(ax25.ProcessBit);


            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == DialogResult.OK)
            {

                using (var ws = new WaveLib.WaveStream(ofd.FileName))
                {

                    ws.Seek(0, System.IO.SeekOrigin.Begin);
                    var bs = new System.IO.BinaryReader(ws);

                    while (bs.BaseStream.Position != bs.BaseStream.Length)
                    {
                        fsk.ProcessSample((bs.ReadInt16() / 32768.0f) * 0.5);
                    }

                }

            }




        }



    }
}
